/*
 * Copyright (c) 2024 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#ifndef GIC_V3_H
#define GIC_V3_H
#include <stdlib/stdint.h>



/* Distributor Control Register, GICD_CTLR */
#define GICD_CTRL_ENABLEGRP1_BIT  (1U << 1)
#define GICD_CTLR_ARE_BIT      (1U << 4)

/* Interrupt Controller Type Register, GICD_TYPER */
#define GICD_TYPER_ITLN_OFF   0U
#define GICD_TYPER_ITLN_LEN   5U
#define GICD_TYPER_CPUNUM_OFF 5U
#define GICD_TYPER_CPUNUM_LEN 3U
#define GICD_TYPER_NUM_LPI_OFF   11U
#define GICD_TYPER_NUM_LPI_LEN   5U

/* Interrupt Controller Software Generated Interrupt Group 1 Register, ICC_SGI1R_EL1 */
#define ICC_SGI1R_EL1_AFF1_OFF   16U
#define ICC_SGI1R_EL1_AFF1_LEN   8U
#define ICC_SGI1R_EL1_INTID_OFF  24U
#define ICC_SGI1R_EL1_INTID_LEN  4U
#define ICC_SGI1R_EL1_AFF2_OFF   32U
#define ICC_SGI1R_EL1_AFF2_LEN   8U
#define ICC_SGI1R_EL1_IRM_OFF    40U
#define ICC_SGI1R_EL1_IRM_LEN    1U
#define ICC_SGI1R_EL1_AFF3_OFF   48U
#define ICC_SGI1R_EL1_AFF3_LEN   8U


void     gic_dist_init(uint64_t base);
void     gic_cpu_init(uint64_t base);
void     gic_hyper_init(uint64_t base);
void     gic_send_sgi(uint32_t irq, uint32_t filter, uint8_t cpulist);
uint32_t gic_get_active_irq(void);
void     gic_enable_irq(uint32_t irq);
void     gic_disable_irq(uint32_t irq);
void     gic_set_eoi(uint32_t irq);
void     gic_set_dir(uint32_t irq);
void     gic_set_priority(uint32_t irq, uint32_t pri);
void     gic_set_cfg(uint32_t irq, uint32_t cfg);
void     gic_set_pendsgi(uint32_t irq);
void     gic_clear_pend(uint32_t irq);
void     gic_set_active(uint32_t irq);
void     gic_clear_active(uint32_t irq);
void     gic_set_targets(uint32_t irq, uint32_t target);
uint32_t gic_read_typer();
void     gic_set_pend(uint32_t irq);

#endif
